package academic.emailClient.view;

import org.apache.cayenne.map.QueryBuilder;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.*;
import org.apache.lucene.util.Version;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;

public class IndexingTheMails {

	static FileReader fr ;
	static BufferedReader buffer;
	private static File rootFolder; 
	private static String SEPARATOR = File.separator;
	private static String EMAIL_CLIENT_ROOT = "Email Folders\\Inbox";
	private static String EMAIL_CLIENT_INDEXING_ROOT = "Email Folders Index";
	
	private static String RELATIVE_PATH = ".";
	private static String INDEXPATH="Index";

/**
 * this method used to create the indexing of the mails that we ve got based on the
 * Recipient Email, Sender Email,Subject, the body message and the date
 * 
 * @throws IOException
 */

	public static void main(String[] arg0) throws IOException{
				
		rootFolder = new File(".", EMAIL_CLIENT_ROOT);		
	  // Directory indexStorage = new SimpleFSDirectory(new File(RELATIVE_PATH,INDEXPATH));	    
		Directory indexStorage = new SimpleFSDirectory(new File(".", EMAIL_CLIENT_INDEXING_ROOT ));
	  @SuppressWarnings("deprecation")
		IndexWriter writer = new IndexWriter(indexStorage,
                new StandardAnalyzer(Version.LUCENE_CURRENT),
                true, IndexWriter.MaxFieldLength.LIMITED);
		writer.setUseCompoundFile(false);
		Iterator<File> files = FileUtils.iterateFiles(rootFolder, null, true);
		
		String line="";
		String bodyMsgBuffer="";
		while( files.hasNext() ){
			Document doc = new Document();
			File file = files.next();
			fr = new FileReader(file);
			buffer = new BufferedReader(fr);		   
			try{
				while ((line=buffer.readLine())!=null){
					String values[] = line.split("/");
					String v[]=values;
					
					if (values.length != 1){
						if ( values[0].equals("FROM"))
							doc.add(new Field("FROM",values[1],Field.Store.YES,Field.Index.NOT_ANALYZED));
						else if (values[0].equals("TO"))	
							doc.add(new Field("TO",values[1],Field.Store.YES,Field.Index.NOT_ANALYZED));
						else if (values[0].equals("SUBJECT"))
							doc.add(new Field("SUBJECT",values[1],Field.Store.YES,Field.Index.NOT_ANALYZED));
					
						else if (values[0].equals("BODY_MESSAGE"))
						{
							bodyMsgBuffer=values[1];
							line=buffer.readLine();
							v = line.split("/");
							
							while (! v[0].equals("DATE"))
							{
								System.out.println("here");
									bodyMsgBuffer=bodyMsgBuffer+" "+line;
									line=buffer.readLine();
									v = line.split("/");
								
							}
					//		doc.add(new Field("BODY_MESSAGE",values[1],Field.Store.YES,Field.Index.NOT_ANALYZED));
							doc.add(new Field("BODY_MESSAGE",bodyMsgBuffer,Field.Store.YES,Field.Index.NOT_ANALYZED));
							
							System.out.println("HELOO  "+bodyMsgBuffer);
						}
						
						values=v;
						if (values[0].equals("DATE"))
							doc.add(new Field("DATE",values[1],Field.Store.YES,Field.Index.NOT_ANALYZED));
						else if (values[0].equals("CC"))
							buffer.readLine();
					}
				}//while
				doc.add(new Field("PATH",file.getPath(),Field.Store.YES,Field.Index.NOT_ANALYZED));
				System.out.println("Indexing done");
				writer.addDocument(doc);
				buffer.close();
				fr.close();
			}
			catch (IOException e) {
				System.err.println("Error: " + e);
			}
		}
		writer.optimize();
		writer.close();
	}//main 


	
/**
 * This method used to search in the mails that matches the user's criteria
 * @param userQuery
 * @throws IOException
 * @throws ParseException
 */
	public  void searchInTheMails(ArrayList<String> userQuery) throws IOException, ParseException {

		File indexDir = new File(EMAIL_CLIENT_INDEXING_ROOT);

		Directory fsDir = FSDirectory.open(indexDir);

		@SuppressWarnings("deprecation")
		IndexSearcher is = new IndexSearcher(fsDir,true);
		TopScoreDocCollector collector =
				TopScoreDocCollector.create(10, true);
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
		
		@SuppressWarnings("deprecation")
		QueryParser queryParser = new QueryParser(Version.LUCENE_CURRENT,
				"FROM",
				new StandardAnalyzer(Version.LUCENE_CURRENT)  );
		        Query query;
			    query=queryParser.parse("*:*");
				Query[] quer=new Query[4];
						BooleanQuery booleanQuery = new BooleanQuery();
				
						if(!userQuery.get(0).equals(""))
							{
							Term term = new Term("FROM", userQuery.get(0));							
							quer[0]= new WildcardQuery(term);
							booleanQuery.add(quer[0], BooleanClause.Occur.MUST);
							}
						if(!userQuery.get(1).equals(""))
						{
							Term term1 = new Term("TO", userQuery.get(1));
							quer[1] = new WildcardQuery(term1);
							booleanQuery.add(quer[1], BooleanClause.Occur.MUST);
							
						}
						if(!userQuery.get(2).equals(""))
						{
							Term term2 = new Term("SUBJECT", userQuery.get(2));
							quer[2] = new WildcardQuery(term2);
							booleanQuery.add(quer[2], BooleanClause.Occur.MUST);
						}	
						  if(!userQuery.get(3).equals(""))
						  {
								Term term3 = new Term("BODY_MESSAGE", userQuery.get(3)+"*" );
								quer[3] = new WildcardQuery(term3);
								queryParser.setAllowLeadingWildcard( true );
								booleanQuery.add(quer[3], BooleanClause.Occur.MUST);
								
						  }
							
						query=query.combine(quer);
						System.out.print(booleanQuery);

						//query = new WildcardQuery(term+term1);
						
						//is.search(query, collector);
						is.search(booleanQuery, collector);
						
						ScoreDoc[] hits = collector.topDocs().scoreDocs;
						if(hits.length != 0){
							for ( ScoreDoc scoreDoc : hits ){
								Document d = is.doc(scoreDoc.doc);
								System.out.println( scoreDoc.score + " " + d.get("PATH") );

							}
						}else
							JOptionPane.showMessageDialog(null,"No match found");
	}
}//class



